﻿namespace Hotel.Web.Controllers
{
    using System;
    using System.Collections.Generic;
    using System.Drawing;
    using System.Drawing.Printing;
    using System.Web.Mvc;
    using Hotel.Module.Management.Models;
    using Hotel.Module.Resources.Models;
    using Hotel.Web.Helpers;
    using Hotel.Web.Models;
    using ManagementModels = Hotel.Module.Management.Models;
    using ManagementModule = Hotel.Module.Management;
    using ResourcesModule = Hotel.Module.Resources;
    using System.Text;

    /// <summary>
    /// Settle In / Settle Out logic
    /// </summary>
    public class CheckInOutController : Controller
    {
        [HttpGet]
        [Authorize(Roles = "Reception")]
        public ActionResult Index()
        {
            return View();
        }

        [HttpPost]
        [Authorize(Roles = "Reception")]
        public ActionResult Index(CheckInOut order)
        {
            try
            {
                if (order.ModeType == Hotel.Web.Views.CheckInOut.CheckInOutResources.MoveIn)
                {
                    CheckIn model = null;
                    using (ManagementModule.ManagementController m_ManagementController = Helpers.ServiceLocator.Instance.GetService(typeof(ManagementModule.IManagement)) as ManagementModule.ManagementController)
                    {
                        Order modelOrder = m_ManagementController.GetOrderByID(order.OrderNumber);
                        if (modelOrder != null)
                        {
                            model = CheckIn.FromDomainModel(modelOrder);

                            if (order.OrderType == Hotel.Web.Views.CheckInOut.CheckInOutResources.Room) model.IsRoom = true;
                            if (order.OrderType == Hotel.Web.Views.CheckInOut.CheckInOutResources.Hall) model.IsRoom = false;

                            return View("CheckIn", model);
                        }
                        else
                        {
                            ModelState.AddModelError("", Hotel.Web.Views.CheckInOut.CheckInOutResources.OrderIDError);
                            return View(order);
                        }
                    }
                }

                if (order.ModeType == Hotel.Web.Views.CheckInOut.CheckInOutResources.MoveOut)
                {
                    //CheckOut for both Room and Hall
                    if (order.OrderType == Hotel.Web.Views.CheckInOut.CheckInOutResources.Room || order.OrderType == Hotel.Web.Views.CheckInOut.CheckInOutResources.Hall)
                    {
                        using (ManagementModule.ManagementController m_ManagementController = Helpers.ServiceLocator.Instance.GetService(typeof(ManagementModule.IManagement)) as ManagementModule.ManagementController)
                        {
                            Order modelOrder = m_ManagementController.GetOrderByID(order.OrderNumber);
                            if (modelOrder != null)
                            {
                                CheckOut model = Hotel.Web.Models.CheckOut.FromDomainModel(modelOrder);
                                return View("CheckOut", model);
                            }
                            else
                            {
                                ModelState.AddModelError("", Hotel.Web.Views.CheckInOut.CheckInOutResources.OrderIDError);
                                return View();
                            }
                        }
                    }
                }
            }
            catch { }
            return View("Error");
        }

        [HttpPost]
        [Authorize(Roles = "Reception")]
        public ActionResult CheckInConfirmation(CheckIn order)
        {
            CheckIn newOrder = CheckInOrder(order);
            if (newOrder != null)
            {
                #region validation logic
                if (order.OutDate < order.InDate)
                {
                    ModelState.AddModelError("", Hotel.Web.Views.OrderRoom.RoomOrder.OutDateError);
                }
                #endregion
                if (ModelState.IsValid)
                {
                    return View("SuccessOrder", newOrder);
                }
            }
            return View("CheckIn", newOrder);
        }

        [HttpPost]
        [Authorize(Roles = "Reception")]
        public ActionResult PrintCheckOut(CheckOut order)
        {
            using (ManagementModule.ManagementController m_ManagementController = Helpers.ServiceLocator.Instance.GetService(typeof(ManagementModule.IManagement)) as ManagementModule.ManagementController)
            {
                Order modelOrder = m_ManagementController.GetOrderByID(order.OrderNumber);
                modelOrder.State = OrderState.Billed;
                using (ResourcesModule.HotelResourcesController m_ResourcesController = Helpers.ServiceLocator.Instance.GetService(typeof(ResourcesModule.IResourseManagment)) as ResourcesModule.HotelResourcesController)
                {
                    m_ResourcesController.FreeRoomsByOrderID(modelOrder.ID);
                    m_ResourcesController.SaveChanges();
                }
                m_ManagementController.SaveChanges();
            }

            order.CheckOutPrint = CheckOutPreparePrintOrder(order);
            return View("PrintCheckOut", order);
        }

        public string CheckOutPreparePrintOrder(CheckOut order)
        {
            using (ManagementModule.ManagementController m_ManagementController = Helpers.ServiceLocator.Instance.GetService(typeof(ManagementModule.IManagement)) as ManagementModule.ManagementController)
            using (ResourcesModule.HotelResourcesController m_ResourcesController = Helpers.ServiceLocator.Instance.GetService(typeof(ResourcesModule.IResourseManagment)) as ResourcesModule.HotelResourcesController)
            {
                StringBuilder s = new StringBuilder();
                s.Append("Dark Deer Hotel").AppendLine(String.Empty);
                if (order.ActionType == Hotel.Web.Views.CheckInOut.CheckInOutResources.Full)
                {

                    s.AppendLine(String.Empty).Append(Hotel.Web.Views.CheckInOut.CheckInOutResources.DetailedCheck).AppendLine(String.Empty);
                    double sum = 0;

                    Order modelOrder = m_ManagementController.GetOrderByID(order.OrderNumber);
                    foreach (var serviceID in modelOrder.IncludedServices)
                    {
                        var item = m_ResourcesController.GetServiceByID(serviceID);
                        s.AppendFormat("{0} {1} {2}", item.Name, Hotel.Web.Views.CheckInOut.CheckInOutResources.price, item.Cost).AppendLine(String.Empty);
                        sum += item.Cost;
                    }

                    s.AppendLine(String.Empty).AppendFormat("{0} {1}{2}", Hotel.Web.Views.CheckInOut.CheckInOutResources.TotalPrice, System.Environment.NewLine, sum).AppendLine(String.Empty);
                }
                else
                {
                    s.AppendLine(String.Empty).AppendLine(Hotel.Web.Views.CheckInOut.CheckInOutResources.ShortCheck).AppendLine(String.Empty);
                    double sum = 0;
                    foreach (var item in order.Services)
                    {
                        sum += item.Price;
                    }
                    s.AppendFormat("{0} {1}", Hotel.Web.Views.CheckInOut.CheckInOutResources.TotalPrice, sum).AppendLine(String.Empty);
                }

                return s.ToString();
            }
        }

        public CheckIn CheckInOrder(CheckIn order)
        {
            lock (Lockers._mutex)
            {
                CheckIn result = null;
                using (ManagementModule.ManagementController m_ManagementController = Helpers.ServiceLocator.Instance.GetService(typeof(ManagementModule.IManagement)) as ManagementModule.ManagementController)
                {
                    Order modelOrder = m_ManagementController.GetOrderByID(order.OrderID);
                    using (ResourcesModule.HotelResourcesController m_ResourcesController = Helpers.ServiceLocator.Instance.GetService(typeof(ResourcesModule.IResourseManagment)) as ResourcesModule.HotelResourcesController)
                        {

                            RoomType type = RoomType.Standart;
                            switch (modelOrder.RoomType)
                            {
                                case ManagementModels.ItemTypes.Suit: type = RoomType.Suit;
                                    break;
                                case ManagementModels.ItemTypes.SemiSuit: type = RoomType.SemiSuit;
                                    break;
                                default: break;
                            }

                            m_ResourcesController.FreeRoomsByOrderID(modelOrder.ID);
                            m_ResourcesController.SaveChanges();
                            List<Room> freeRooms = m_ResourcesController.GetFreeRooms(order.InDate, order.OutDate, type);

                            if (freeRooms.Count >= order.RoomNum)
                            {
                                order.AssignTo(modelOrder);

                                Period period = new Period();
                                period.OrderID = modelOrder.ID;
                                period.InDate = modelOrder.InDate;
                                period.OutDate = modelOrder.OutDate;
                                modelOrder.RoomPackage.Clear();
                                List<int> roomPackage = new List<int>();
                                for (int i = 0; i < modelOrder.NumberOfRooms; i++)
                                {
                                    freeRooms[i].Periods.Add(period);
                                    modelOrder.RoomPackage.Add(freeRooms[i].Number);
                                    roomPackage.Add(freeRooms[i].Number);
                                    m_ResourcesController.Storage.Update(freeRooms[i]);
                                }
                                modelOrder.State = OrderState.Opened;
                                result = CheckIn.FromDomainModel(modelOrder);
                                result.RoomPackage.AddRange(roomPackage);
                            }
                            else
                            {
                                Period period = new Period();
                                period.OrderID = modelOrder.ID;
                                period.InDate = modelOrder.InDate;
                                period.OutDate = modelOrder.OutDate;
                                
                                for (int i = 0; i < modelOrder.RoomPackage.Count; i++)
                                {
                                    var room = freeRooms.Find(p => p.Number == modelOrder.RoomPackage[i]);
                                    room.Periods.Add(period);
                                    m_ResourcesController.Storage.Update(room);
                                }
                                modelOrder.State = ManagementModels.OrderState.Preordered;
                            }
                            m_ManagementController.Storage.Update(modelOrder);
                            m_ManagementController.SaveChanges();
                            m_ResourcesController.SaveChanges();
                        }
                }
                return result;
            }
        }


    }
}
